/** @brief Define classes that write log records during normal processing, and applying logs during restart recovery
 *
 *  log.h
 *  kangmodb
 *
 *  Created by 강모 김 on 11. 4. 24..
 *  Copyright 2011 강모소프트. All rights reserved.
 *
 */

#ifndef _KD_LOG_H_
#define _KD_LOG_H_ (1)

#include "kdInfra.h"
#include "transLogBuffer.h"
#include "key.h"
#include "data.h"


class stgLogApplyer
{
public :
	KD_VOID redo(const void * log)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
	KD_VOID undo(const void * log)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
private:	
	KD_VOID redoInsert(stgTableId tableId, const stgKey & key, const stgData & data)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
	KD_VOID redoUpdate(stgTableId tableId, const stgKey & key, const stgData & data)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
	KD_VOID redoDelete(stgTableId tableId, const stgKey & key)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
	KD_VOID undoInsert(stgTableId tableId, const stgKey & key, const stgData & data)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
	KD_VOID undoUpdate(stgTableId tableId, const stgKey & key, const stgData & data)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
	KD_VOID undoDelete(stgTableId tableId, const stgKey & key)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
};

/** @brief A file containing log records. It maintains a sequence of log records in a circular queue.
 */
class stgLogStream
{
private :	
	// TODO : create a file that keeps log records in the same way that a circular queue does.
	KD_VOID append(void * logData, int logDataLength)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
public :
	stgLogStream() {}

	/** @brief Create a new log stream backing the content on the given log file path.
	 */
	KD_VOID create(const KD_STRING & logFilePath)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}

	/** @brief Open a log stream. The give file path is used for storing the content of log stream
	 */
	KD_VOID open(const KD_STRING & logFilePath)
	{
		KD_TRY
		{
			// TODO : Implement
			KD_ASSERT(0);
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}

	/** @brief Append the transaction log buffer to this log stream.
	 * A transaction sends the whole content of its log buffer to the log stream when it commits.
	 * No log record is sent to the log stream before the transaction commit, but they are kept in transaction log buffer.
	 */
	KD_VOID append(const stgTransactionLogBuffer & logBuffer)
	{
		void * logData;
		int logDataLength;
		KD_TRY 
		{
			// BUGBUG need a mutext on log stream 
			KD_ASSERT(0);
			
			for(logBuffer.initLogChunkIteration(), logBuffer.iterateLogChunk(&logData, &logDataLength);
				logData != NULL && logDataLength > 0 ; 
				logBuffer.iterateLogChunk(&logData, &logDataLength) )
			{
				KD_CALL( append( logData, logDataLength ) );
			}
		}
		KD_CATCH
		KD_FINALLY
		KD_END
	}
};

#endif /* _KD_LOG_H_ */